package com.szwistar.common.comm;

import com.szwistar.common.datastruct.Utils;

import org.apache.log4j.PropertyConfigurator;
import org.apache.mina.core.buffer.IoBuffer;

import java.nio.ByteOrder;

public class ZktCmd extends ZktFrame implements AsyncCommand {
	public static final short CMD_SYN  = 1000;
	public static final short CMD_OPEN = 31;

	public static ZktCmd cmdSyn() {
		return new ZktCmd(CMD_SYN, null);
	}

	public static ZktCmd cmdOpenDoor(int doorId) {
		return new ZktCmd(CMD_OPEN, Utils.LEintToBytes(doorId));
	}

	// 重发次数
	protected int resendCount = 3;
	// 已经发送的次数
	protected int resentCount = 0;
	// 重发间隔(ms)
	protected int resendInterval = 3000;
	// 本消息的发送者
	protected AsyncTranceiver sender;

	@Override
	public void setResendCount(int resendCount) { this.resendCount = resendCount; }
	@Override
	public int getResendCount() { return resendCount; }
	@Override
	public void setResendInterval(int resendInterval) { this.resendInterval = resendInterval; }
	@Override
	public int getResendInterval() { return resendInterval; }
	@Override
	public int getResentCount() { return resentCount; }
	@Override
	public int increaseResentCount() { return ++resentCount; }
	@Override
	public AsyncTranceiver getSender() { return sender; }
	@Override
	public void setSender(AsyncTranceiver sender) { this.sender = sender; }

	@Override
	public Object getSource() { return (sender == null) ? null : sender.getOwner(); }
	@Override
	public Object getTarget() { return (sender == null) ? null : sender.getOwner(); }

	public ZktCmd(short cmd, byte[] bytes) {
		super(cmd, (short)0, (short)0, bytes);
	}

	public IoBuffer encode() {
		int len = (bytes == null) ? 8 : 8+bytes.length;
		IoBuffer buf = IoBuffer.allocate(8+len);
		buf.order(ByteOrder.LITTLE_ENDIAN);

		buf.put(PREFIX);
		buf.putInt(len);
		buf.putShort(cmd);
		buf.putShort((short)0);
		buf.putShort(sessionId);
		buf.putShort(fsn);
		if(bytes != null) { buf.put(bytes); }
		int end = buf.position();

		// 放入校验和
		buf.position(10);
		buf.putShort((short)(-1 - sum(buf, 8, len)));
		buf.position(end);

		buf.flip();
		//LOGCOMM.debug("ZktFrame数据帧编码输出：\n\t[{}]", buf.getHexDump());
		return buf;
	}

	@Override
	public boolean matchResponse(Object message) {
		if(!(message instanceof ZktFrame)) { return false; }

		ZktFrame frame = (ZktFrame) message;
		return frame.fsn == fsn;
	}

	@Override
	public String toString() {
		return "ZktCmd [cmd=" + cmd + ", sessionId=" + sessionId + ", fsn=" + fsn + ", bytes=" + Utils.bytesToHexString(bytes)	+ "]";
	}

	// for test only
	public static void main(String[] args) throws InterruptedException {
		PropertyConfigurator.configure("conf/log4j.properties");
		ZktCmd frame = new ZktCmd((short)0x03E8, null);
		frame.encode();
	}
}
